package com.sharer.last.base.utils;

import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.util.HtmlUtils;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static org.apache.commons.lang3.StringUtils.substring;

/***
 * 字符串工具类,
 * 继承 hutool StrUtil
 */
public class StringUtil extends StrUtil {

    private static Pattern linePattern = Pattern.compile("_(\\w)");
    private static Pattern humpPattern = Pattern.compile("[A-Z]");


    private static final String S_INT = "0123456789";
    private static final String S_STR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    private static final String S_ALL = S_INT + S_STR;


    /**
     * 是否包含字符串
     *
     * @param str  验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inString(String str, String... strs) {
        if (str != null) {
            for (String s : strs) {
                if (str.equals(trim(s))) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 把string array or list用给定的符号symbol连接成一个字符串
     *
     * @param list   需要处理的列表
     * @param symbol 链接的符号
     * @return 处理后的字符串
     */
    public static String joinString(List list, String symbol) {
        String result = "";
        if (CollectionUtil.isNotEmpty(list)) {
            for (Object o : list) {
                if(o!=null) {
                    String temp = o.toString();
                    if (temp.trim().length() > 0) {
                        result += (temp + symbol);
                    }
                }
            }
            if (result.length() > 1) {
                result = result.substring(0, result.length() - 1);
            }
        }
        return result;
    }

    /**
     * Checks if the specified string list is not empty.
     */
    public static boolean areNotEmpty(String... values) {
        boolean result = true;
        if (values == null || values.length == 0) {
            result = false;
        } else {
            for (String value : values) {
                result &= !isEmpty(value);
            }
        }
        return result;
    }

    /**
     * Converts a universally encoded string into a Chinese character encoding.
     */
    public static String unicodeToChinese(String unicode) {
        StringBuilder out = new StringBuilder();
        if (!isEmpty(unicode)) {
            for (int i = 0; i < unicode.length(); i++) {
                out.append(unicode.charAt(i));
            }
        }
        return out.toString();
    }

    /**
     * @param content
     * @param charset
     * @return
     * @throws UnsupportedEncodingException
     */
    public static byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            return content.getBytes();
        }
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
        }
    }

    /**
     * 下划线转驼峰
     *
     * @param str
     * @param firstUpperCase 首字母是否大小
     * @return
     */
    public static String underlineToHump(String str, boolean firstUpperCase) {
        if (null == str || "".equals(str)) {
            return str;
        }
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);

        str = sb.toString();
        if (firstUpperCase) {
            str = str.substring(0, 1).toUpperCase() + str.substring(1);
        }
        return str;
    }

    public static String underlineToHump(String str) {
        return underlineToHump(str, true);
    }

    /**
     * 字符串驼峰转下划线格式
     *
     * @param param 需要转换的字符串
     * @return 转换好的字符串
     */
    public static String camelToUnderline(String param) {
        if (isEmpty(param)) {
            return EMPTY;
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c) && i > 0) {
                sb.append(UNDERLINE);
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    /**
     * 字符串下划线转驼峰格式
     *
     * @param param 需要转换的字符串
     * @return 转换好的字符串
     */
    public static String underlineToCamel(String param) {
        if (isEmpty(param)) {
            return EMPTY;
        }
        String temp = param.toLowerCase();
        int len = temp.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = temp.charAt(i);
            if (c == CharUtil.UNDERLINE) {
                if (++i < len) {
                    sb.append(Character.toUpperCase(temp.charAt(i)));
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 驼峰转下划线
     *
     * @param str
     * @return
     */
    public static String humpToUnderline(String str) {
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        // return sb.toString();
        return sb.toString().substring(1);
    }

    /**
     * 将字符串首字母大写
     *
     * @param str
     * @return
     */
    public static String fristToUpCase(String str) {
        if (str != null && str.length() > 0) {
            str = str.substring(0, 1).toUpperCase() + str.substring(1);
        }
        return str;
    }

    /**
     * 将字符串首字母小写
     *
     * @param str
     * @return
     */
    public static String fristToLoCase(String str) {
        if (str != null && str.length() > 0) {
            str = str.substring(0, 1).toLowerCase() + str.substring(1);
        }
        return str;
    }

    /**
     * 隐藏手机号 中间六位
     *
     * @param phone
     * @return
     */
    public static String hidePhone(String phone) {
        return substring(phone, 0, 3) + "******" + substring(phone, phone.length() - 2, phone.length());
    }


    /**
     * 转义HTML用于安全过滤
     *
     * @param html html
     * @return {String}
     */
    public static String escapeHtml(String html) {
        return HtmlUtils.htmlEscape(html);
    }

    /**
     * 清理字符串，清理出某些不可见字符
     *
     * @param txt 字符串
     * @return {String}
     */
    public static String cleanChars(String txt) {
        return txt.replaceAll("[ 　`·•�\\f\\t\\v\\s]", "");
    }


    /***返回区间随机整数
     * @param min
     * @param max
     * @return
     */
    public static int randomNum(int min, int max) {
        return new Random().nextInt(max - min + 1) + min;
    }


    /***生成指定长度的字母和数字的随机组合字符串
     *
     * @param count
     * @return
     */
    public static String randomAlphanumeric(int count) {
        return RandomStringUtils.randomAlphanumeric(count);
    }

    /***生成随机数字字符串
     *
     * @param count
     * @return
     */
    public static String randomNumeric(int count) {
        return RandomStringUtils.randomNumeric(count);
    }

    /***生成随机[a-z]字符串，包含大小写
     *
     * @param count
     * @return
     */
    public static String randomAlphabetic(int count) {
        return RandomStringUtils.randomAlphabetic(count);
    }


    /**
     * 字符串[values]按照指定分隔符[split]进行拆分，解析成Long集合
     * <p>
     * eg:
     * values=1,2,3  split=,
     * return=[1,2,3]
     * eg:
     * values=,,,1,,2,,3,,  split=,
     * return=[1,2,3]
     *
     * @param values 按照指定分隔符拼接的字符串
     * @param split  分隔符
     * @return
     */
    public static List<Long> strToList(String values, String split) {
        if (values == null || values.isEmpty()) {
            return new ArrayList<>();
        }
        if (split == null || split.isEmpty()) {
            split = ",";
        }
        try {
            return Arrays.stream(split(values, split)).map((v) -> Long.valueOf(v)).collect(Collectors.toList());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    /**
     * 转换为Integer集合<br>
     *
     * @param str 结果被转换的值
     * @return 结果
     */
    public static List<Integer> strToIntList(String str) {
        return Arrays.asList(strToIntArray(str));
    }

    /***字符串为数组
     *
     * @param values
     * @param split
     * @return
     */
    public static String[] strToArray(String values, String split) {
        if (values == null || values.isEmpty()) {
            return new String[]{};
        }
        if (split == null || split.isEmpty()) {
            split = ",";
        }

        if (values.indexOf(split) == -1) {
            return new String[]{values};
        } else {
            return values.split(split);
        }

    }


    /**
     * 默认,分割
     *
     * @param str 被转换的值
     * @return 结果
     */
    public static String[] strToArray(String str) {
        return strToArray(str, ",");
    }

    /*** 转换字符串成数组
     *
     * @param str
     * @returns {*[]}
     */
    public static String[] convertStrToArray(String str) {
        if (str.indexOf(",") > -1) {
            return strToArray(str, ",");
        } else if (str.indexOf("，") > -1) {
            return strToArray(str, "，");
        } else if (str.indexOf("\r\n") > -1) {
            return strToArray(str, "\r\n");
        } else if (str.indexOf("\n") > -1) {
            return strToArray(str, "\n");
        } else {
            return new String[]{str};
        }
    }

    /**
     * 字符串转换为Integer数组
     *
     * @param split 分隔符
     * @param str   被转换的值
     * @return 结果
     */
    public static Integer[] strToIntArray(String str, String split) {
        if (isEmpty(str)) {
            return new Integer[]{};
        }
        String[] arr = str.split(split);
        final Integer[] ints = new Integer[arr.length];
        for (int i = 0; i < arr.length; i++) {
            final Integer v = ConvertUtil.toInt(arr[i], 0);
            ints[i] = v;
        }
        return ints;
    }

    public static Integer[] strToIntArray(String str) {
        return strToIntArray(str, ",");
    }

    public static String[] listToArray(List<String> strList) {
        return strList.toArray(new String[strList.size()]);
    }

    /**
     * 创建StringBuilder对象
     *
     * @return StringBuilder对象
     */
    public static StringBuilder builder() {
        return new StringBuilder();
    }

    /**
     * 创建StringBuilder对象
     *
     * @param capacity 初始大小
     * @return StringBuilder对象
     */
    public static StringBuilder builder(int capacity) {
        return new StringBuilder(capacity);
    }

    /**
     * 创建StringBuilder对象
     *
     * @param strs 初始字符串列表
     * @return StringBuilder对象
     */
    public static StringBuilder builder(CharSequence... strs) {
        final StringBuilder sb = new StringBuilder();
        for (CharSequence str : strs) {
            sb.append(str);
        }
        return sb;
    }


    /**
     * 创建StringBuilder对象
     *
     * @param sb   初始StringBuilder
     * @param strs 初始字符串列表
     * @return StringBuilder对象
     */
    public static StringBuilder appendBuilder(StringBuilder sb, CharSequence... strs) {
        for (CharSequence str : strs) {
            sb.append(str);
        }
        return sb;
    }

    /**
     * 将args去掉两边空格连接起来
     *
     * @param args 待连接的字符串
     * @author jianggm
     */
    public static String append(String... args) {
        StringBuilder sb = new StringBuilder();
        for (String arg : args) {
            sb.append(arg.trim());
        }
        return sb.toString();
    }

    /***
     * 正则获取字符
     *  String regex = "/([0-9a-zA-Z_-]+)/";
     * @param regex
     * @param source
     * @return
     */
    public static String getMatcher(String regex, String source) {
        String result = "";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(source);
        while (matcher.find()) {
            result = matcher.group(1);
        }
        return result;
    }

    /***字符串是否包含str字符
     *
     * @param str
     * @return
     */
    public static boolean hasText(@Nullable String str) {
        return StringUtils.hasText(str);
    }


    public static String collectionToCommaDelimitedString(@Nullable Collection<?> coll) {
        return StringUtils.collectionToDelimitedString(coll, ",");
    }

    /**
     * 匿名手机号
     *
     * @param mobile
     * @return 152****4799
     */
    public static String hideMobile(String mobile) {

        if (isEmpty(mobile)) {
            return null;
        }
        return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }

    /**
     * 匿名银行卡号
     *
     * @param bankCard
     * @return
     */
    public static String hideBankCard(String bankCard) {
        if (isEmpty(bankCard)) {
            return null;
        }
        return bankCard.replaceAll("(\\d{5})\\d{5}\\d{2}(\\d{4})", "$1****$2");
    }

    /**
     * 匿名身份证
     *
     * @param idCard
     * @return 4304*****7733
     */
    public static String hideIdCard(String idCard) {

        if (isEmpty(idCard)) {
            return null;
        }
        return idCard.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1*****$2");
    }


    /*** 自动补零
     * @param num 当前数字
     * @param len  总长度
     * @return
     */
    public static String numberFill(Integer num, int len) {
        String result = "";
        if (len > 0) {
            result = String.format("%0" + len + "d", num);
        }
        return result;
    }

    /***通过连接获取host
     *
     * @param link
     * @return
     */
    public static String getHost(String link) {
        URL url;
        String host = "";
        try {
            url = new URL(link);
            host = url.getHost();
        } catch (MalformedURLException e) {
        }
        return host;
    }

    /**
     * 去掉字符串指定的前缀
     *
     * @param str    字符串名称
     * @param prefix 前缀数组
     * @return
     */
    public static String removePrefix(String str, String[] prefix) {
        if (StringUtils.isEmpty(str)) {
            return "";
        } else {
            if (null != prefix) {
                String[] prefixArray = prefix;

                for (int i = 0; i < prefix.length; ++i) {
                    String pf = prefixArray[i];
                    if (str.toLowerCase().matches("^" + pf.toLowerCase() + ".*")) {
                        return str.substring(pf.length());//截取前缀后面的字符串
                    }
                }
            }

            return str;
        }
    }

    /***去掉字符串下滑线前缀
     *
     * @param str
     * @return life_product -> product
     */
    public static String removeLinePrefix(String str) {
        return str.substring(str.indexOf("_") + 1);
    }

    /*** 去掉字符串下滑线后缀
     *
     * @param str
     * @return life_product -> life
     */
    public static String removeLineSuffix(String str) {
        return str.substring(0, str.indexOf("_"));
    }

    /****字典字符串解析
     *
     * 支持格式如:
     * KEY:VALUE
     * KEY:VALUE
     * @return
     */
    public static Map<String, String> parseDict(String content) {
        if (isEmpty(content)) {
            return null;
        }
        Map<String, String> tempMap = new HashMap<>();
        try {
            String[] tempArr = convertStrToArray(content);
            for (String str : tempArr) {
                String[] temp = str.split(":");
                if (temp.length > 0) {
                    tempMap.put(temp[0], temp[1]);
                }
            }
            return tempMap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 数组字符串 重新排序
    public static String sortArrayStr(String arrayStr) {
        String[] riskCodeArray = StringUtil.strToArray(arrayStr);
        Arrays.sort(riskCodeArray);
        return org.apache.commons.lang3.StringUtils.join(riskCodeArray, ",");
    }
}
